package com.ly.web.controller.king;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.gson.Gson;
import com.kingdee.bos.webapi.entity.IdentifyInfo;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.KingConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.KingOrgEntity;
import com.ly.heart.domain.WarehouseEntity;
import com.ly.heart.domain.king.BaseChildBo;
import com.ly.heart.domain.king.base.BaseModelBo;
import com.ly.heart.domain.king.base.WarehouseBo;
import com.ly.heart.domain.request.KingBaseRequest;
import com.ly.heart.domain.response.KingBaseResponse;
import com.ly.heart.domain.response.KingBaseResponseError;
import com.ly.heart.domain.response.KingBaseResponseSuccessEntity;
import com.ly.heart.service.IKingOrgService;
import com.ly.heart.service.IWarehouseService;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.heart.util.KingCommonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Api (value = "WarehouseRemote", tags = "推基础数据-仓库")
@RestController
@RequestMapping ("/heart/WarehouseRemote")
@Slf4j
public class WarehouseRemote {

    @Resource
    private IWarehouseService iWarehouseService;
    @Resource
    private IKingOrgService iKingOrgService;

    @ApiOperation ("同步拉取金蝶仓库")
    @RequestMapping ("pull")
    public AjaxResult queryList () {
        KingOrgEntity orgEntity = iKingOrgService.getOne ( new LambdaQueryWrapper<KingOrgEntity> ().eq ( KingOrgEntity :: getOrgId, CurrentUserUtil.getCompanyId () ).eq ( KingOrgEntity :: getIsDisabled, false ) );
        if ( orgEntity == null ) {
            throw new CustomException ( "请先至系统管理中配置金蝶账套！" );
        }
        IdentifyInfo identifyInfo = KingCommonUtil.getIdentifyInfo ( orgEntity );
        K3CloudApi client = new K3CloudApi ( identifyInfo );
        /**
         * 参数顺序：
         * 编码、名称、仓库属性、仓库地址、负责人、联系电话、描述、直运仓、管易仓、库存状态类型、默认库存状态、默认收料状态、允许即时负库存、允许MRP计划、允许锁库、参与预警、参与拣练、启用仓位管理、不参与可发量统计、拣货优先级、仓位维度数据列表显示格式
         */
        String jsonData = "{\"FormId\":\"" + KingConstUtil.BD_STOCK + "\",\"FieldKeys\":\"FNumber,FName,FStockProperty,FAddress,FPrincipal.FNumber,FTel,FDescription,FIsZYStock,FIsGYStock,FStockStatusType,FDefStockStatusId.FNumber,FDefReceiveStatusId.FNumber,FAllowMinusQty,FAllowMRPPlan,FAllowLock,FAvailableAlert,FAvailablePicking,FIsOpenLocation,FNotExpQty,FSortingPriority,FLocListFormatter\",\"FilterString\":[],\"OrderString\":\"\",\"TopRowCount\":0,\"StartRow\":0,\"Limit\":2000,\"SubSystemId\":\"\"}";
        try {
            //调用接口
            List<List<Object>> lists = client.executeBillQuery ( jsonData );
            for ( int i = 0; i < lists.size (); i++ ) {
                List<Object> objects = lists.get ( i );
                //根据code查询是否已存在该结算方式
                String bizCode = (String) objects.get ( 0 );
                WarehouseEntity one = iWarehouseService.getOne ( new LambdaQueryWrapper<WarehouseEntity> ().eq ( WarehouseEntity :: getWareCode, bizCode ) );
                if ( one == null ) {
                    one = new WarehouseEntity ();
                    one.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
                    one.setWareCode ( bizCode );
                    one.setCreateOrg ( CurrentUserUtil.getCompanyId () );
                    one.setUseOrg ( CurrentUserUtil.getCompanyId () );
                    one.setWareName ( String.valueOf ( objects.get ( 1 ) ) );
                    one.setWareAttribute ( String.valueOf ( objects.get ( 2 ) ) );
                    one.setAddress ( String.valueOf ( objects.get ( 3 ) ) );
                    one.setWareManagement ( String.valueOf ( objects.get ( 4 ) ) );
                    one.setTelPhone ( String.valueOf ( objects.get ( 5 ) ) );
                    one.setRemarks ( String.valueOf ( objects.get ( 6 ) ) );
                    Boolean dir = (Boolean) objects.get ( 7 );
                    one.setIsDirect ( dir ? "1" : "2" );
                    Boolean gy = (Boolean) objects.get ( 8 );
                    one.setIsGy ( gy ? "1" : "2" );
                    one.setStockStateType ( String.valueOf ( objects.get ( 9 ) ) );
                    one.setDefaultStockState ( String.valueOf ( objects.get ( 10 ) ) );
                    one.setDefaultReceivingState ( String.valueOf ( objects.get ( 11 ) ) );
                    Boolean inventory = (Boolean) objects.get ( 12 );
                    one.setAllowRealInventory ( inventory ? "1" : "2" );
                    Boolean allowMrp = (Boolean) objects.get ( 13 );
                    one.setAllowRealInventory ( allowMrp ? "1" : "2" );
                    Boolean allowLockWare = (Boolean) objects.get ( 14 );
                    one.setAllowRealInventory ( allowLockWare ? "1" : "2" );
                    Boolean allowWarning = (Boolean) objects.get ( 15 );
                    one.setAllowRealInventory ( allowWarning ? "1" : "2" );
                    Boolean enableWareRegion = (Boolean) objects.get ( 16 );
                    one.setAllowRealInventory ( enableWareRegion ? "1" : "2" );
                    Boolean allowPicking = (Boolean) objects.get ( 17 );
                    one.setAllowRealInventory ( allowPicking ? "1" : "2" );
                    Boolean noAllowCount = (Boolean) objects.get ( 18 );
                    one.setAllowRealInventory ( noAllowCount ? "1" : "2" );
                    one.setPickingPriority ( String.valueOf ( objects.get ( 19 ) ) );
                    one.setDisplayFormat ( String.valueOf ( objects.get ( 20 ) ) );
                    one.setCreateBy ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
                    one.setCreateTime ( DateUtils.getNowDate () );
                    one.setIsSend ( KingConstUtil.KING_DATA_IS_SEND_YES );
                    iWarehouseService.save ( one );
                }
            }
        } catch ( Exception e ) {
            throw new RuntimeException ( "同步仓库失败" );
        }
        return AjaxResult.success ( "同步仓库成功" );
    }


    /**
     * 同步所有结算方式到金蝶
     * @return
     */
    @ApiOperation ("同步发送仓库金蝶")
    @RequestMapping ("push")
    public AjaxResult push () throws Exception {
        KingOrgEntity orgEntity = iKingOrgService.getOne ( new LambdaQueryWrapper<KingOrgEntity> ().eq ( KingOrgEntity :: getOrgId, CurrentUserUtil.getCompanyId () ).eq ( KingOrgEntity :: getIsDisabled, false ) );
        if ( orgEntity == null ) {
            throw new CustomException ( "请先至系统管理中配置金蝶账套！" );
        }
        IdentifyInfo identifyInfo = KingCommonUtil.getIdentifyInfo ( orgEntity );
        K3CloudApi client = new K3CloudApi ( identifyInfo );
        List<WarehouseEntity> list = iWarehouseService.list ( new LambdaQueryWrapper<WarehouseEntity> ().eq ( WarehouseEntity :: getIsSend, KingConstUtil.KING_DATA_IS_SEND_NO ) );
        if ( CollectionUtils.isEmpty ( list ) ) {
            return AjaxResult.error ( "暂无新数据可推！" );
        }
        batchSave ( list, client );
        submit ( list, client );
        audit ( list, client );
        return AjaxResult.success ( "推送仓库成功。" );
    }


    /**
     * 推送结算方式
     * @param list
     * @param client
     * @throws Exception
     */
    private void batchSave (List<WarehouseEntity> list, K3CloudApi client) throws Exception {
        KingBaseRequest request = new KingBaseRequest ();
        List<BaseModelBo> bos = new ArrayList<> ();
        list.forEach ( ware -> {
            WarehouseBo bo = new WarehouseBo ();
            bo.setFNumber ( ware.getWareCode () );
            bo.setFName ( ware.getWareName () );
            bo.setFStockProperty ( StringUtils.isBlank ( ware.getWareAttribute () ) ? "" : ware.getWareAttribute () );
            if ( StringUtils.isNotBlank ( ware.getAddress () ) ) {
                bo.setFAddress ( ware.getAddress () );
            }
            if ( StringUtils.isNotBlank ( ware.getTelPhone () ) ) {
                bo.setFTel ( ware.getTelPhone () );
            }
            if ( StringUtils.isNotBlank ( ware.getIsDirect () ) ) {
                bo.setFIsZYStock ( ware.getIsDirect ().equals ( "1" ) ? true : false );
            }
            if ( StringUtils.isNotBlank ( ware.getIsGy () ) ) {
                bo.setFIsGYStock ( ware.getIsGy ().equals ( "1" ) ? true : false );
            }
            bo.setFStockStatusType ( ware.getStockStateType () );
            if ( StringUtils.isNotBlank ( ware.getDefaultStockState () ) ) {
                BaseChildBo base = new BaseChildBo ().setFNumber ( ware.getDefaultStockState () );
                bo.setFDefStockStatusId ( base );
            }
            if ( StringUtils.isNotBlank ( ware.getDefaultReceivingState () ) ) {
                BaseChildBo base = new BaseChildBo ().setFNumber ( ware.getDefaultReceivingState () );
                bo.setFDefReceiveStatusId ( base );
            }
            if ( StringUtils.isNotBlank ( ware.getAllowRealInventory () ) ) {
                bo.setFAllowMinusQty ( ware.getAllowRealInventory ().equals ( "1" ) ? true : false );
            }
            if ( StringUtils.isNotBlank ( ware.getAllowLockWare () ) ) {
                bo.setFAllowLock ( ware.getAllowLockWare ().equals ( "1" ) ? true : false );
            }
            if ( StringUtils.isNotBlank ( ware.getAllowMrp () ) ) {
                bo.setFAllowMRPPlan ( ware.getAllowMrp ().equals ( "1" ) ? true : false );
            }
            if ( StringUtils.isNotBlank ( ware.getEnableWareRegion () ) ) {
                bo.setFIsOpenLocation ( ware.getEnableWareRegion ().equals ( "1" ) ? true : false );
            }
            if ( StringUtils.isNotBlank ( ware.getAllowWarning () ) ) {
                bo.setFAvailableAlert ( ware.getAllowWarning ().equals ( "1" ) ? true : false );
            }
            if ( StringUtils.isNotBlank ( ware.getAllowPicking () ) ) {
                bo.setFAvailablePicking ( ware.getAllowPicking ().equals ( "1" ) ? true : false );
            }
            if ( StringUtils.isNotBlank ( ware.getNoAllowCount () ) ) {
                bo.setFNotExpQty ( ware.getNoAllowCount ().equals ( "1" ) ? true : false );
            }
            if ( StringUtils.isNotBlank ( ware.getPickingPriority () ) ) {
                bo.setFSortingPriority ( ware.getPickingPriority () );
            }
            bo.setFLocListFormatter ( ware.getDisplayFormat () );
            bos.add ( bo );
        } );
        request.setModel ( bos );
        String s = JSONObject.toJSONString ( request );
        log.info ( "bos-》{}", bos );
        log.info ( "s->{}", s );
        String resultJson = client.batchSave ( KingConstUtil.BD_STOCK, s );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () == true ) {
            //添加成功，进行提交
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "仓库-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.info ( "{} 推送成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "仓库-推送失败：【" + sb + "】" );
        }
    }


    /**
     * 提交结算方式
     * @param list
     * @param client
     */
    private void submit (List<WarehouseEntity> list, K3CloudApi client) throws Exception {
        WarehouseBo bo = new WarehouseBo ();
        List<String> strings = new ArrayList<> ();
        list.forEach ( bankEntity -> {
            strings.add ( bankEntity.getWareCode () );
        } );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.submit ( KingConstUtil.BD_STOCK, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () == true ) {
            //提交成功
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "仓库-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.error ( "{} 提交成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "仓库提交失败：【" + sb + "】" );
        }
    }

    /**
     * 结算方式审核
     * @param list
     * @param client
     */
    private void audit (List<WarehouseEntity> list, K3CloudApi client) throws Exception {
        WarehouseBo bo = new WarehouseBo ();
        List<String> strings = new ArrayList<> ();
        list.forEach ( bankEntity -> {
            strings.add ( bankEntity.getWareCode () );
        } );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.audit ( KingConstUtil.BD_STOCK, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () == true ) {
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "仓库-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.info ( "{} 审核成功", sb );
            //修改为已推送状态
            list.forEach ( ware -> {
                iWarehouseService.update ( new LambdaUpdateWrapper<WarehouseEntity> ().
                        set ( WarehouseEntity :: getIsSend, KingConstUtil.KING_DATA_IS_SEND_YES ).
                        eq ( WarehouseEntity :: getId, ware.getId () ) );
            } );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "仓库审核失败：【" + sb + "】" );
        }
    }

}
